package com.relation.db;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.naming.NamingException;

import org.hibernate.Session;

import com.relation.domain.Resource;
import com.relation.domain.User;
import com.relation.utils.PagingResult;

public class Dao {
	
	static Logger _logger = Logger.getLogger(Dao.class.getName());
	
	public static final Dao INSTANCE = new Dao();
	
	private Dao()
	{
		
	}
	
	public Serializable saveResource(Resource resource)
	{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Serializable o = session.save(resource);

        session.getTransaction().commit();
        return o;
	}
	
	public void deleteResource(Resource resource)
	{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        session.delete(resource);

        session.getTransaction().commit();
	}
	
	public PagingResult<Resource> getResource(int type, int offset, int limit)
	{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		long total = ( (Long) session.createQuery("select count(*) from Resource as r where r.type = :type")
				.setInteger("type", type)
				.iterate().next() ).longValue();
		List<Resource> resources = (List<Resource>) session.createQuery(
	    "from Resource as r where r.type = :type")
	    .setInteger("type", type)
	    .setFirstResult(offset)
	    .setMaxResults(limit)
	    .list();
		session.getTransaction().commit();
		PagingResult<Resource> result = new PagingResult<Resource>();
		result.setItems(resources);
		result.setTotal(total);
		return result;
	}
	
	public void updateUser(long uid, String nick, String session) throws NamingException, SQLException
	{
		Connection conn = null;
		PreparedStatement statement = null;
		try
		{
			conn = DBUtils.getConnection();
			String sql = "update user_t set session_c=?, last_login_c=? where user_id_c=?";
			statement = conn.prepareStatement(sql);
			statement.setString(1, session);
			statement.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
			statement.setLong(3, uid);
			int result = statement.executeUpdate();
			if (result == 0)
			{
				sql = "insert into user_t(user_id_c, nick_c, session_c, last_login_c) values(?,?,?,?)";
				statement = conn.prepareStatement(sql);
				statement.setLong(1, uid);
				statement.setString(2, nick);
				statement.setString(3, session);
				statement.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
			}
			statement.executeUpdate();
		}
		finally
		{
			DBUtils.close(conn, statement, null);
		}
	}
	
	public String getSessionByUser(String nick) throws NamingException, SQLException
	{
		Connection conn = null;
		PreparedStatement statement = null;
		ResultSet rs = null;
		try
		{
			conn = DBUtils.getConnection();
			String sql = "select session_c from user_t where nick_c=?";
			statement = conn.prepareStatement(sql);
			statement.setString(1, nick);
			rs = statement.executeQuery();
			if (rs.next())
			{
				return rs.getString("session_c");
			}
		}
		finally
		{
			DBUtils.close(conn, statement, null);
		}
		return null;
	}
	
	public List<User> getUsers() throws NamingException, SQLException
	{
		Connection conn = null;
		PreparedStatement statement = null;
		ResultSet rs = null;
		try
		{
			conn = DBUtils.getConnection();
			String sql = "select * from user_t order by last_login_c limit 50 offset 0";
			statement = conn.prepareStatement(sql);
			rs = statement.executeQuery();
			List<User> users = new ArrayList<User>();
			while (rs.next())
			{
				User user = new User();
				user.setNick(rs.getString("nick_c"));
				user.setLastLogin(rs.getDate("last_login_c"));
				users.add(user);
			}
			return users;
		}
		finally
		{
			DBUtils.close(conn, statement, rs);
		}
	}
}
